<?php

namespace ApigilityCompany\Service;

use ApigilityAddress\Service\AddressService;
use ApigilityCatworkFoundation\Base\ApigilityEventAwareObject;
use ApigilityCompany\DoctrineEntity\Company;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\Hydrator\ClassMethods as ClassMethodsHydrator;
use Zend\Hydrator\ObjectProperty as ObjectPropertyHydrator;

class CompanyService extends ApigilityEventAwareObject
{
    const EVENT_Company_CREATED = 'CompanyService.EventCompanyCreated';
    const EVENT_Company_NICKNAME_UPDATE = 'CompanyService.EVENT_Company_NICKNAME_UPDATE';

    protected $em;
    protected $classMethodsHydrator;
    protected $objectPropertyHydrator;

    /**
     * @var \ZF\MvcAuth\Identity\AuthenticatedIdentity
     */
    protected $authIdentity;

    protected $services;

    /**
     * @var IdentityService
     */
    protected $identityService;

    /**
     * @var OccupationService
     */
    protected $occupationService;

    /**
     * @var IncomeLevelService
     */
    protected $incomeLevelService;

    /**
     * @var AddressService
     */
    protected $addressService;

    public function __construct(ServiceManager $services)
    {

        $this->services = $services;
        $this->em = $services->get('Doctrine\ORM\EntityManager');
        $this->identityService = $services->get('ApigilityUser\Service\IdentityService');
       // $this->occupationService = $services->get('ApigilityCompany\Service\OccupationService');
       // $this->incomeLevelService = $services->get('ApigilityCompany\Service\IncomeLevelService');
        $this->addressService = $services->get('ApigilityAddress\Service\AddressService');
        $this->classMethodsHydrator = new ClassMethodsHydrator();
        $this->objectPropertyHydrator = new ObjectPropertyHydrator();

    }

    /**
     * 获取商家列表
     *
     * @param $params
     * @return DoctrinePaginatorAdapter
     */
    public function getCompanys($params)
    {
        $qb = new QueryBuilder($this->em);
        $qb->select('b')->from('ApigilityAd\DoctrineEntity\Banner', 'b')->orderBy(new Expr\OrderBy('b.id', 'DESC'));

        $where = null;
        if (isset($params->position_id)) {
            $qb->innerJoin('b.positions', 'p');
            if (!empty($where)) $where .= ' AND ';
            $where = 'p.id = :position_id';
        }

        if (!empty($where)) {
            $qb->where($where);
            if (isset($params->position_id)) $qb->setParameter('position_id', $params->position_id);
        }

        $doctrine_paginator = new DoctrineToolPaginator($qb->getQuery());
        return new DoctrinePaginatorAdapter($doctrine_paginator);
    }


    /**
     * 创建一个商家
     * @param $data
     * @return Company
     */
    public function createCompany($data)
    {
        $Company = new Company();
        $Company->setId($data->Company_id);

        if (isset($data->nickname)) $Company->setNickname($data->nickname);
        else {
            $identity = $this->identityService->getIdentity($data->Company_id);
            $nickname = '商家';
            if (!empty($identity->getPhone())) $nickname = $nickname.substr($identity->getPhone(), 0, 3).'****'.substr($identity->getPhone(), -4, 4);
            else $nickname = $nickname.$identity->getId();
            $Company->setNickname($nickname);
        }

        $this->hydrateCompanyData($Company, $data);

        $this->em->persist($Company);
        $this->em->flush();

        $this->getEventManager()->trigger(self::EVENT_Company_CREATED, $this, ['Company' => $Company]);

        return $Company;
    }

    /**
     * 获取单个商家信息
     *
     * @param $Company_id
     * @return \ApigilityCompany\DoctrineEntity\Company
     * @throws Exception\CompanyNotExistException
     */
    public function getCompany($Company_id)
    {
        $Company = $this->em->find('ApigilityCompany\DoctrineEntity\Company', $Company_id);
        if (empty($Company)) throw new Exception\CompanyNotExistException();
        return $Company;
    }

    /**
     * 更新单个商家信息
     *
     * @param $Company_id
     * @param $data
     * @return Company
     */
    public function updateCompany($Company_id, $data)
    {
        $Company = $this->getCompany($Company_id);

        $this->hydrateCompanyData($Company, $data);

        $this->em->flush();

        if (isset($data->nickname)) {
            // 触发事件
            $this->getEventManager()->trigger(self::EVENT_Company_NICKNAME_UPDATE, $this, ['Company' => $Company]);
        }

        return $Company;
    }

    /**
     * 获取已登录的商家对象
     * @return \ApigilityCompany\DoctrineEntity\Company
     */
    public function getAuthCompany()
    {
        $this->authIdentity = $this->services->get('api-identity');
        return  $this->getCompany($this->authIdentity->getRoleId());
    }

    /**
     * @param Company $Company
     * @param $data
     */
    private function hydrateCompanyData(Company $Company, $data)
    {
        if (isset($data->nickname)) $Company->setNickname($data->nickname);
        if (isset($data->avatar)) $Company->setAvatar($data->avatar);
        if (isset($data->sex)) $Company->setSex($data->sex);
        if (isset($data->age)) $Company->setAge($data->age);
        if (isset($data->stature)) $Company->setStature($data->stature);
        if (isset($data->weight)) $Company->setWeight($data->weight);
        if (isset($data->education)) $Company->setEducation($data->education);
        if (isset($data->emotion)) $Company->setEmotion($data->emotion);
        if (isset($data->zodiac)) $Company->setZodiac($data->zodiac);
        if (isset($data->chinese_zodiac)) $Company->setChineseZodiac($data->chinese_zodiac);

        if (isset($data->birthday)) {
            $datetime = new \DateTime();
            $datetime->setTimestamp($data->birthday);
            $Company->setBirthday($datetime);
        }

        if (isset($data->income_level)) $Company->setIncomeLevel($this->incomeLevelService->getIncomeLevel($data->income_level));
        if (isset($data->occupation)) $Company->setOccupation($this->occupationService->getOccupation($data->occupation));
        if (isset($data->residence_address)) $Company->setResidenceAddress($this->addressService->getAddress($data->residence_address));
        if (isset($data->census_register_address)) $Company->setCensusRegisterAddress($this->addressService->getAddress($data->census_register_address));
    }
}